package com.binhthuan.catechist.server.service;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.binhthuan.catechist.server.ErrorObject;
import com.binhthuan.catechist.server.QueryObject;
import com.binhthuan.catechist.server.ResponseObject;
import com.binhthuan.catechist.server.bus.TrainerBUS;
import com.binhthuan.catechist.server.domain.Area;
import com.binhthuan.catechist.server.domain.Course;
import com.binhthuan.catechist.server.domain.Trainer;
import com.binhthuan.catechist.server.domain.TrainerStatus;
import com.binhthuan.catechist.server.util.FileUtils;
import com.binhthuan.catechist.server.util.URLUtils;
import com.binhthuan.catechist.server.util.preferences.ConfigKeys;
import com.binhthuan.catechist.server.util.preferences.SystemGlobals;
import com.binhthuan.catechist.shared.Utilities;
import com.binhthuan.catechist.shared.constant.Action;
import com.binhthuan.catechist.shared.constant.Parameter;

public class TrainerServlet extends AbstractServlet {

    /**
     * 
     */
    private static final long serialVersionUID = -7071020314608637745L;

    @Override
    protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        addTrainer(request, response);
    }

    @Override
    protected void fetch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (Action.GET_TRAINERS_BY_COURSE.equals(request.getParameter(Parameter.OPERATION_INFO))) {
            getTrainersByCourse(request, response);
        } else if (Action.GET_ALL_TRAINERS.equals(request.getParameter(Parameter.OPERATION_INFO))) {
            getAllTrainers(request, response);
        } else if (Action.GET_INACTIVE_TRAINERS.equals(request.getParameter(Parameter.OPERATION_INFO))) {
            getInactiveTrainers(request, response);
        } else if (Action.GET_TEMPORARY_DELETE_TRAINERS.equals(request.getParameter(Parameter.OPERATION_INFO))) {
            getTemporaryDeleteTrainers(request, response);
        } else if (request.getParameter(Parameter.ID) != null) {
            getTrainerById(request, response);
        } else {
            getActiveTrainers(request, response);
        }
    }

    @Override
    protected void remove(HttpServletRequest request, HttpServletResponse response, boolean confirmation)
            throws ServletException, IOException {
        deleteTrainer(request, response, confirmation);
    }

    @Override
    protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        updateTrainer(request, response);
    }

    private void getTrainerById(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String idString = request.getParameter(Parameter.ID);
        try {
            Integer id = (idString == null) ? null : Integer.parseInt(idString);

            TrainerBUS bus = new TrainerBUS();
            Trainer obj = bus.getTrainerById(id);
            if (obj == null) {
                ErrorObject error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.ID, getMessagesFactory().itemNotFound(getConstantsFactory().trainee()));
                sendResponse(error.toJson());
                return;
            }

            sendResponse(new ResponseObject(obj).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getTrainersByCourse(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int classId = Integer.parseInt(request.getParameter(Parameter.COURSE));
            int startRow = Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            TrainerBUS bus = new TrainerBUS();
            QueryObject result = bus.getTrainersByCourse(classId, startRow, endRow - startRow);

            sendResponse(new ResponseObject(result).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getActiveTrainers(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int startRow = (request.getParameter(Action.Information.START_ROW) == null) ? -1 : Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = (request.getParameter(Action.Information.END_ROW) == null) ? -1 : Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            TrainerBUS bus = new TrainerBUS();
            QueryObject result = bus.getActiveTrainers(startRow, endRow - startRow);

            sendResponse(new ResponseObject(result).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getInactiveTrainers(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int startRow = Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            TrainerBUS bus = new TrainerBUS();
            QueryObject result = bus.getInactiveTrainers(startRow, endRow - startRow);

            sendResponse(new ResponseObject(result).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getTemporaryDeleteTrainers(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        try {
            int startRow = Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            TrainerBUS bus = new TrainerBUS();
            QueryObject result = bus.getTemporaryDeleteTrainers(startRow, endRow - startRow);

            sendResponse(new ResponseObject(result).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getAllTrainers(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int startRow = Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            TrainerBUS bus = new TrainerBUS();
            QueryObject result = bus.getAllTrainers(startRow, endRow - startRow);

            sendResponse(new ResponseObject(result).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void addTrainer(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String isActiveString = request.getParameter(Parameter.ACTIVE);
        String isTemporaryDeleteString = request.getParameter(Parameter.TEMPORARY_DELETE);
        String address = request.getParameter(Parameter.ADDRESS);
        String areaIdString = request.getParameter(Parameter.AREA);
        String avatar = request.getParameter(Parameter.AVATAR);
        String birthdayString = request.getParameter(Parameter.BIRTHDAY);
        String firstName = request.getParameter(Parameter.FIRST_NAME);
        String lastName = request.getParameter(Parameter.LAST_NAME);
        String isMaleString = request.getParameter(Parameter.MALE);
        String patronSaint = request.getParameter(Parameter.PATRON_SAINT);
        String phone = request.getParameter(Parameter.PHONE);
        String feastDayString = request.getParameter(Parameter.FEAST_DAY);
        String comment = request.getParameter(Parameter.COMMENT);
        String joinDateString = request.getParameter(Parameter.JOIN_DATE);
        String email = request.getParameter(Parameter.EMAIL);
        String statusIdString = request.getParameter(Parameter.STATUS);
        String courseIdString = request.getParameter(Parameter.CURRENT_COURSE);

        try {
            boolean isMale = (isMaleString == null) ? false : Boolean.parseBoolean(isMaleString);
            boolean isActive = (isActiveString == null) ? false : Boolean.parseBoolean(isActiveString);
            boolean isTemporaryDelete = (isTemporaryDeleteString == null) ? false : Boolean.parseBoolean(isTemporaryDeleteString);
            Date birthday = (birthdayString == null) ? null : dateFormatter.parse(birthdayString);
            Date feastDay = (feastDayString == null) ? null : dateFormatter.parse(feastDayString);
            Date joinDate = (feastDayString == null) ? null : dateFormatter.parse(joinDateString);
            Integer areaId = (areaIdString == null) ? null : Integer.parseInt(areaIdString);
            Integer statusId = (statusIdString == null) ? null : Integer.parseInt(statusIdString);
            Integer courseId = (courseIdString == null) ? null : Integer.parseInt(courseIdString);

            // Move avatar to correct folder
            if (!Utilities.isNullOrEmpty(avatar)) {
                if (FileUtils.checkFileExist(getRealPath(avatar))) {
                    avatar = FileUtils.moveFile(getRealPath(avatar), SystemGlobals.getValue(ConfigKeys.AVATAR_DIR));
                    avatar = URLUtils.getRelativePath(avatar, SystemGlobals.getApplicationPath());
                }
            }

            Trainer obj = new Trainer();
            obj.setAddress(address);
            obj.setAvatar(avatar);
            obj.setBirthday(birthday);
            obj.setFeastDay(feastDay);
            obj.setJoinDate(joinDate);
            obj.setComment(comment);
            obj.setEmail(email);
            obj.setFirstName(firstName);
            obj.setLastName(lastName);
            obj.setMale(isMale);
            obj.setPatronSaint(patronSaint);
            obj.setPhone(phone);
            obj.setActive(isActive);
            obj.setTemporaryDelete(isTemporaryDelete);

            if (areaId != null) {
                Area area = new Area();
                area.setId(areaId);
                obj.setArea(area);
            }

            if (courseId != null) {
                Course currentCourse = new Course();
                currentCourse.setId(courseId);
                obj.setCurrentCourse(currentCourse);
            }

            if (statusId != null) {
                TrainerStatus status = new TrainerStatus();
                status.setId(statusId);
                obj.setStatus(status);
            }

            TrainerBUS bus = new TrainerBUS();
            if (bus.save(obj)) {
                sendResponse(new ResponseObject(obj).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void deleteTrainer(HttpServletRequest request, HttpServletResponse response, boolean confirmation)
            throws IOException {
        String idString = request.getParameter(Parameter.ID);
        try {
            Integer id = (idString == null) ? null : Integer.parseInt(idString);

            TrainerBUS bus = new TrainerBUS();
            Trainer obj = bus.getTrainerById(id);
            if (obj == null) {
                ErrorObject error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.ID, getMessagesFactory().itemNotFound(getConstantsFactory().trainee()));
                sendResponse(error.toJson());
                return;
            }

            if (!confirmation) {
                obj.setTemporaryDelete(true);
                bus.save(obj);
                sendResponse(new ResponseObject((Object) null).toJson());
            } else {
                bus.delete(obj);
                sendResponse(new ResponseObject((Object) null).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void updateTrainer(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String idString = request.getParameter(Parameter.ID);
        String isActiveString = request.getParameter(Parameter.ACTIVE);
        String isTemporaryDeleteString = request.getParameter(Parameter.TEMPORARY_DELETE);
        String address = request.getParameter(Parameter.ADDRESS);
        String areaIdString = request.getParameter(Parameter.AREA);
        String avatar = request.getParameter(Parameter.AVATAR);
        String birthdayString = request.getParameter(Parameter.BIRTHDAY);
        String firstName = request.getParameter(Parameter.FIRST_NAME);
        String lastName = request.getParameter(Parameter.LAST_NAME);
        String isMaleString = request.getParameter(Parameter.MALE);
        String patronSaint = request.getParameter(Parameter.PATRON_SAINT);
        String phone = request.getParameter(Parameter.PHONE);
        String feastDayString = request.getParameter(Parameter.FEAST_DAY);
        String comment = request.getParameter(Parameter.COMMENT);
        String joinDateString = request.getParameter(Parameter.JOIN_DATE);
        String email = request.getParameter(Parameter.EMAIL);
        String statusIdString = request.getParameter(Parameter.STATUS);
        String courseIdString = request.getParameter(Parameter.CURRENT_COURSE);

        try {
            boolean isMale = (isMaleString == null) ? false : Boolean.parseBoolean(isMaleString);
            boolean isActive = (isActiveString == null) ? false : Boolean.parseBoolean(isActiveString);
            boolean isTemporaryDelete = (isTemporaryDeleteString == null) ? false : Boolean.parseBoolean(isTemporaryDeleteString);
            Date birthday = (birthdayString == null) ? null : dateFormatter.parse(birthdayString);
            Date feastDay = (feastDayString == null) ? null : dateFormatter.parse(feastDayString);
            Date joinDate = (feastDayString == null) ? null : dateFormatter.parse(joinDateString);
            Integer areaId = (areaIdString == null) ? null : Integer.parseInt(areaIdString);
            Integer statusId = (statusIdString == null) ? null : Integer.parseInt(statusIdString);
            Integer courseId = (courseIdString == null) ? null : Integer.parseInt(courseIdString);
            Integer id = (idString == null) ? null : Integer.parseInt(idString);

            // Move avatar to correct folder
            if (!Utilities.isNullOrEmpty(avatar)) {
                if (FileUtils.checkFileExist(getRealPath(avatar))) {
                    avatar = FileUtils.moveFile(getRealPath(avatar), SystemGlobals.getValue(ConfigKeys.AVATAR_DIR));
                    avatar = URLUtils.getRelativePath(avatar, SystemGlobals.getApplicationPath());
                }
            }

            Trainer obj = new Trainer();
            obj.setId(id);
            obj.setAddress(address);
            obj.setAvatar(avatar);
            obj.setBirthday(birthday);
            obj.setFeastDay(feastDay);
            obj.setJoinDate(joinDate);
            obj.setComment(comment);
            obj.setEmail(email);
            obj.setFirstName(firstName);
            obj.setLastName(lastName);
            obj.setMale(isMale);
            obj.setPatronSaint(patronSaint);
            obj.setPhone(phone);
            obj.setActive(isActive);
            obj.setTemporaryDelete(isTemporaryDelete);

            if (areaId != null) {
                Area area = new Area();
                area.setId(areaId);
                obj.setArea(area);
            }

            if (courseId != null) {
                Course currentCourse = new Course();
                currentCourse.setId(courseId);
                obj.setCurrentCourse(currentCourse);
            }

            if (statusId != null) {
                TrainerStatus status = new TrainerStatus();
                status.setId(statusId);
                obj.setStatus(status);
            }

            TrainerBUS bus = new TrainerBUS();
            if (bus.save(obj)) {
                sendResponse(new ResponseObject(obj).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }
}
